// src/utils/request.ts
import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse } from 'axios';
import { ElMessage } from 'element-plus'; // 如果使用其他UI库可替换

// 定义响应数据的基本结构（根据后端接口规范调整）
interface ResponseData<T = any> {
  code: number;
  data: T;
  message: string;
}

// 扩展axios请求配置
interface RequestOptions extends AxiosRequestConfig {
  // 是否显示loading（需要实现loading逻辑可在此扩展）
  showLoading?: boolean;
  // 是否显示错误提示
  showError?: boolean;
}

class Request {
  private instance: AxiosInstance;

  constructor() {
    this.instance = axios.create({
      baseURL: import.meta.env.VITE_API_BASE_URL, // 从环境变量获取
      timeout: 10000,
      headers: {
        'Content-Type': 'application/json;charset=UTF-8',
      },
    });

    // 请求拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // 添加认证token（示例）
        const token = localStorage.getItem('token');
        if (token) {
          config.headers.Authorization = `Bearer ${token}`;
        }
        return config;
      },
      (error) => {
        return Promise.reject(error);
      }
    );

    // 响应拦截器
    this.instance.interceptors.response.use(
      (response: AxiosResponse<ResponseData>) => {
        const res = response.data;
        // 根据状态码处理（这里假设200为成功）
        if (res.code === 200) {
          return Promise.resolve(res.data);
        }
        // 处理业务错误
        this.handleError(res.code, res.message);
        return Promise.reject(res);
      },
      (error) => {
        // 处理HTTP错误
        this.handleHttpError(error);
        return Promise.reject(error);
      }
    );
  }

  // 处理业务错误
  private handleError(code: number, message: string) {
    // 根据业务状态码处理（示例）
    switch (code) {
      case 401:
        // 跳转到登录页
        break;
      case 403:
        // 权限不足处理
        break;
      // ...其他状态码
    }
    ElMessage.error(message);
  }

  // 处理HTTP错误
  private handleHttpError(error: any) {
    let errorMessage = '请求失败';
    if (error.response) {
      // 请求成功发出且服务器响应状态码不在2xx范围
      const status = error.response.status;
      switch (status) {
        case 400:
          errorMessage = '请求参数错误';
          break;
        case 404:
          errorMessage = '资源未找到';
          break;
        case 500:
          errorMessage = '服务器错误';
          break;
        // ...其他状态码处理
      }
    } else if (error.request) {
      // 请求已发出但没有收到响应
      errorMessage = '网络连接异常，请检查网络';
    } else {
      errorMessage = error.message;
    }
    ElMessage.error(errorMessage);
  }

  // 封装基础请求方法
  public request<T = any>(options: RequestOptions): Promise<T> {
    return this.instance(options);
  }

  // 封装GET方法
  public get<T = any>(url: string, params?: object, config?: RequestOptions): Promise<T> {
    return this.request({ url, method: 'GET', params, ...config });
  }

  // 封装POST方法
  public post<T = any>(url: string, data?: object, config?: RequestOptions): Promise<T> {
    return this.request({ url, method: 'POST', data, ...config });
  }

  // 封装PUT方法
  public put<T = any>(url: string, data?: object, config?: RequestOptions): Promise<T> {
    return this.request({ url, method: 'PUT', data, ...config });
  }

  // 封装DELETE方法
  public delete<T = any>(url: string, params?: object, config?: RequestOptions): Promise<T> {
    return this.request({ url, method: 'DELETE', params, ...config });
  }

  public async requestSSE(
    config: AxiosRequestConfig,
    onMessage: (data: string) => void,
    onError?: (error: Error) => void
  ) {
    try {
      // 使用 Fetch API 实现流式读取
      const response = await fetch(`${import.meta.env.VITE_API_BASE_URL}${config.url}`, {
        method: config.method?.toUpperCase() || 'GET',
        headers: {
          ...this.instance.defaults.headers.common,
          ...config.headers,
          // 'Content-Type': 'text/event-stream',
          'Content-Type': 'application/json',
        },
        body: config.data ? JSON.stringify(config.data) : undefined,
      });

      // 验证响应状态
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      // 创建读取器和文本解码器
      const reader = response.body?.getReader();
      const decoder = new TextDecoder();

      if (!reader) {
        throw new Error('Failed to get stream reader');
      }

      // 持续读取数据流
      while (true) {
        const { done, value } = await reader.read();
        if (done) break;

        const chunk = decoder.decode(value);
        const lines = chunk.split('\n\n');

        lines.forEach((line) => {
          if (line.startsWith('data: ')) {
            onMessage(line.replace('data: ', '').trim());
          }
        });
      }
    } catch (error) {
      onError?.(error instanceof Error ? error : new Error('Stream error'));
    }
  }
}

const request = new Request();

export default request;
